#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>
#include <pthread.h>

#include "uartTool.h"
#include "garbage.h"
#include "pwm.h"
#include "myoled.h"
#include "socket.h"

int serial_fd = -1;
pthread_cond_t cond;
pthread_mutex_t mutex;

static int detect_process(const char *process_name)
{
    int n = -1;
    FILE *strm;
    char buf[128]={0};
    sprintf(buf,"ps -ax | grep %s|grep -v grep", process_name);

    if((strm = popen(buf, "r")) != NULL)
    {
        if(fgets(buf, sizeof(buf), strm) != NULL)
        {
            printf("buf=%s\n",buf);
            n = atoi(buf);
            printf("n=%d\n",n);
        }
    }
    else
        return -1;

    pclose(strm);
    return n;
}

void *pget_voice(void *arg)
{
    int len = 0;
    //定义默认数据
    unsigned char buffer[6] = {0xAA,0x55,0x00,0x00,0x55,0xAA};
    if(-1 == serial_fd)
    {
        printf("%s|%s|%d:open serial failed\n",__FILE__,__func__,__LINE__);
        pthread_exit(0);
    }
    while(1)
    {
        //监听语音模块串口输出
        len = serialGetstring(serial_fd,buffer);
        printf("%s|%s|%d, len=%d\n", __FILE__, __func__, __LINE__,len);
        if(len > 0 && buffer[2] == 0x46)
        {
            printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
            pthread_mutex_lock(&mutex);
            buffer[2] = 0x00;
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
        }
    }
    pthread_exit(0);
}

void *popen_trash_can(void *arg)
{
    pthread_detach(pthread_self());
    unsigned char *buffer = (unsigned char*)arg;

    //开关垃圾桶
    if(buffer[2] == 0x41)
    { 
        pwm_write(PWM_DRY_GARBAGE);
        delay(2000);
        pwm_stop(PWM_DRY_GARBAGE);
    }
    else if(buffer[2] == 0x42)
    {
        pwm_write(PWM_WET_GARBAGE);
        delay(2000);
        pwm_stop(PWM_WET_GARBAGE);
    }
    else if(buffer[2] == 0x43)
    {
        pwm_write(PWM_RECYCLABLE_GARBAGE);
        delay(2000);
        pwm_stop(PWM_RECYCLABLE_GARBAGE);
    }
    else if(buffer[2] == 0x44)
    {
        pwm_write(PWM_HARMFUL_GARBAGE);
        delay(2000);
        pwm_stop(PWM_HARMFUL_GARBAGE);
    }
    else if(buffer[2] == 0x45)
    {
        pwm_stop(PWM_DRY_GARBAGE);
        pwm_stop(PWM_WET_GARBAGE);
        pwm_stop(PWM_RECYCLABLE_GARBAGE);
        pwm_stop(PWM_HARMFUL_GARBAGE);
    }
    pthread_exit(0);
}

void *psend_voice(void *arg)
{
    pthread_detach(pthread_self());
    unsigned char *buffer = (unsigned char*)arg;

    if(-1 == serial_fd)
    {
        printf("%s|%s|%d:open serial failed\n",__FILE__,__func__,__LINE__);
        pthread_exit(0);
    }
    if(NULL != buffer)
    {
        //把收到的数据回传给语音模块，播报垃圾类型
        serialSendstring(serial_fd,buffer,6);
    }
    pthread_exit(0);
}

void *poled_show(void *arg)
{
    pthread_detach(pthread_self());//父子线程分离
    myoled_init();
    oled_show(arg);

    pthread_exit(0);
}

void *pcategory(void *arg)
{
    unsigned char buffer[6] = {0xAA,0x55,0x00,0x00,0x55,0xAA};
    char *category = NULL;
    pthread_t send_voice_tid,trash_tid,oled_tid;

    while(1)
    {
        printf("%s|%s|%d: \n", __FILE__, __func__, __LINE__);
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond,&mutex);
        pthread_mutex_unlock(&mutex);
        printf("%s|%s|%d: \n", __FILE__, __func__, __LINE__);
        
        buffer[2] = 0x00;
        //拍照
        system(WGET_CMD);
        //判断照片是否存在
        if(0 == access(GARBAGE_FILE,F_OK))
        {
            //判断垃圾类型
            category = garbage_category(category);
            if(strstr(category,"干垃圾"))
                buffer[2] = 0x41;
            else if(strstr(category,"湿垃圾"))
                buffer[2] = 0x42;
            else if(strstr(category,"可回收垃圾"))
                buffer[2] = 0x43;
            else if(strstr(category,"有害垃圾"))
                buffer[2] = 0x44;
            else
                buffer[2] = 0x45;
        }
        else
            buffer[2] = 0x45;
        //垃圾桶开关线程
        pthread_create(&trash_tid,NULL,popen_trash_can,(void *)buffer);
        //开语音播报线程
        pthread_create(&send_voice_tid,NULL,psend_voice,(void *)buffer);
        //oled显示线程
        pthread_create(&oled_tid,NULL,poled_show,(void *)buffer);
        //清理图片缓存
        remove(GARBAGE_FILE);
    }
    pthread_exit(0);
}

void *pget_socket(void *arg)
{
    int s_fd = -1;
    int c_fd = -1;
    int n_read = -1;
    char buffer[6];

    struct sockaddr_in c_addr;

    memset(&c_addr,0,sizeof(struct sockaddr_in));

    s_fd = socket_init(IPADDR,IPPORT);
    printf("%s|%s|%d:s_fd=%d\n", __FILE__, __func__, __LINE__, s_fd);
    if(-1 == s_fd)
        pthread_exit(0); 
    int clen = sizeof(struct sockaddr_in);
    while(1)
    {
        c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);

        int keepalive = 1;// 开启TCP KeepAlive功能
        int keepidle = 5;// tcp_keepalive_tim 5s内没收到数据开始发送心跳包
        int keepcnt = 3; // tcp_keepalive_probes 每次发送心跳包的时间间隔,单位秒
        int keepintvl = 3; // tcp_keepalive_intvl 每3s发送一次心跳包

        setsockopt(c_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive,sizeof(keepalive));
        setsockopt(c_fd, SOL_TCP, TCP_KEEPIDLE, (void *) &keepidle, sizeof(keepidle));
        setsockopt(c_fd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcnt, sizeof(keepcnt));
        setsockopt(c_fd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepintvl, sizeof(keepintvl));

        printf("%s|%s|%d:Accept a conection from %s:%d\n",__FILE__,__func__,__LINE__,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
        if(-1 == c_fd)
        {
            perror("accept");
            continue;
        }
        while(1)
        {
            memset(buffer,0,sizeof(buffer));
            n_read = recv(c_fd,buffer,sizeof(buffer),0);
            printf("%s|%s|%d:nread=%d,buffer=%s\n",__FILE__,__func__,__LINE__,n_read,buffer);
            if(n_read > 0)
            {
                if(strstr(buffer,"open"))
                {
                    pthread_mutex_lock(&mutex);
                    pthread_cond_signal(&cond);
                    pthread_mutex_unlock(&mutex);
                }
            }
            else if(0 == n_read || -1 == n_read)
                break;
        }
        close(c_fd);
    }

    pthread_exit(0); 
}

int main(int argc,char *argv[])
{
    int len = 0;
    char *category = NULL;
    int ret = -1;
    pthread_t get_voice_tid,category_tid,get_socket_tid;

    //定义默认数据
    unsigned char buffer[6] = {0xAA,0x55,0x00,0x00,0x55,0xAA};
    //初始化wiringPi
    wiringPiSetup();
    //初始化阿里云接口
    garbage_init();
    //判断mjpg_streamer服务是否开启
    ret = detect_process("mjpg_streamer");
    if(-1 == ret)
    {
        printf("detect process failed\n");
        goto END;
    }
    //打开语音模块设备
    serial_fd = myserialOpen(SERIAL_DEV,BAUD);
    if(-1 == serial_fd)
    {
        printf("open serial failed\n");
        goto END;
    }
    //开语音线程
    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    pthread_create(&get_voice_tid,NULL,pget_voice,NULL);
    //开网络线程
    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    pthread_create(&get_socket_tid,NULL,pget_socket,NULL);
    //开阿里云交互线程
    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    pthread_create(&category_tid,NULL,pcategory,NULL);
    //等待线程结束退出
    pthread_join(get_voice_tid,NULL);
    pthread_join(category_tid,NULL);
    pthread_join(get_socket_tid,NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    close(serial_fd);
END:
    garbage_final();
    return 0;
}